﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SQLite;
using Pixysoft.Framework.XSchEmA.Entity;
using Pixysoft.Framework.XSchEmA;
using System.Data;

namespace Pixysoft.Framework.Noebe.Command
{
    class SQLiteCommandGenerator : ICommandGenerator
    {

        public string GetPagingSQL(string tableName, string pagingColumnName, string condition, int pageCapacity, int pageIndex, bool reverse)
        {
            StringBuilder builder = new StringBuilder();

            builder.AppendFormat("SELECT * FROM {0}", tableName);

            if (!string.IsNullOrEmpty(condition))
            {
                builder.Append(" WHERE ").Append(condition);
            }

            if (reverse)
                builder.AppendFormat(" ORDER BY {0} DESC LIMIT {1}, {2}",
                    pagingColumnName, pageCapacity * pageIndex, pageCapacity);
            else
                builder.AppendFormat(" ORDER BY {0} LIMIT {1}, {2}",
                    pagingColumnName, pageCapacity * pageIndex, pageCapacity);

            return builder.ToString();
        }

        public string GetManualPagingSQL(string sql, string pagingColumnName, int pageCapacity, int pageIndex, bool reverse)
        {
            StringBuilder builder = new StringBuilder();

            builder.Append(sql);

            if (reverse)
            {
                builder.Append(" ORDER BY " + pagingColumnName + " DESC LIMIT " + pageCapacity * pageIndex + ", " + pageCapacity);
            }
            else
            {
                builder.Append(" ORDER BY " + pagingColumnName + " LIMIT " + pageCapacity * pageIndex + ", " + pageCapacity);
            }

            return builder.ToString();
        }

        public string RegularSQL(string sql)
        {
            return sql;
        }

        public IDbConnection GetConnection(string connStr)
        {
            return new SQLiteConnection(connStr);
        }


        public IDataParameter GetParameter(string paraName)
        {
            SQLiteParameter para = new SQLiteParameter();
            para.ParameterName = paraName;
            para.DbType = DbType.String;
            para.SourceColumn = paraName;
            return para;
        }

        public IDataParameter GetParameter(string paraName, DotNetDataType type)
        {
            SQLiteParameter para = new SQLiteParameter();
            para.ParameterName = paraName;
            para.DbType = GetParaType(type);
            para.SourceColumn = paraName;
            return para;
        }

        public IDataParameter GetParameter(ColumnSchema column)
        {
            SQLiteParameter para = new SQLiteParameter(column.ColumnName,
            GetParaType(column.DataType), 0, column.ColumnName);
            para.Direction = ParameterDirection.Input;
            para.IsNullable = column.IsNullable;
            para.SourceVersion = DataRowVersion.Current;
            return para;
        }


        /// <summary>
        /// 取得参数类型
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns></returns>
        private DbType GetParaType(DotNetDataType type)
        {
            switch (type)
            {
                case DotNetDataType.Boolean:
                    return DbType.Boolean;
                case DotNetDataType.Char:
                case DotNetDataType.Int32:
                    return DbType.Int32;

                case DotNetDataType.Single:
                    return DbType.Single;
                case DotNetDataType.Double:
                    return DbType.Double;
                case DotNetDataType.Decimal:
                    return DbType.Decimal;
                case DotNetDataType.Int64:
                    return DbType.Int64;

                case DotNetDataType.DateTime:
                    return DbType.DateTime;

                case DotNetDataType.Byte:
                case DotNetDataType.Object:
                    return DbType.Binary;

                case DotNetDataType.String:
                case DotNetDataType.UNKNOWN:
                default:
                    return DbType.String;
            }
        }
        /// <summary>
        /// 取得参数类型
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns></returns>
        private DbType GetParaType(DataTypeSchema type)
        {
            switch (Pixysoft.EnumCoder.ToEnum<SQLiteDataTypeCollection>(type.DataType))
            {
                case SQLiteDataTypeCollection.INTEGER:
                    return DbType.Int64;
                case SQLiteDataTypeCollection.NONE:
                    return DbType.Binary;
                case SQLiteDataTypeCollection.NUMERIC:
                    return DbType.Double;
                case SQLiteDataTypeCollection.REAL:
                    return DbType.Double;
                case SQLiteDataTypeCollection.TEXT:
                default:
                    return DbType.String;
            }
        }
    }
}
